package itsm.isperp.framework.service.impl;

import itsm.isperp.framework.domain.UploadInfo;
import itsm.isperp.framework.service.UploadService;
import itsm.isperp.framework.upload.UploadChecker;
import itsm.isperp.framework.upload.UploadPersister;
import itsm.isperp.framework.upload.UploadPreference;
import itsm.isperp.framework.upload.impl.DefaultUploadPreferenceImpl;

import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.Collection;

import javax.servlet.http.HttpServletRequest;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * {@link UploadService}接口的默认实现.
 * <p>
 * 实现了如下功能:<br/>
 * <ol>
 * <li>
 * 将上传的文件保存到数据库或文件系统,由在调用上传工具页面时向url附加参数实现.<br/>
 * 如将CustomDropdown的url写成:<br/>
 * <code>/upload/d5/upload.jsp?store=db:blob</code>.<br/>
 * 其中store=db:blob参数代表要将文件存储到blob库中 .<br/>
 * 其余的可用值有:<br/>
 * <ul>
 * <li>db:clob,代表存储到clob库中;</li>
 * <li>file:D:/myUploadedFileStore代表存储到D盘的myUploadedFileStore文件夹中;</li>
 * <li>file:/WEB-INF/isperp/isperpUploadedFileStore代表存储到应用根目录下的WEB-INF/isperp/
 * isperpUploadedFileStore文件夹中</li>
 * </ul>
 * <li>限制上传文件的类型,由在调用上传工具页面时向url附加参数实现.<br/>
 * 如将CustomDropdown的url写成:<br/>
 * <code>/upload/d5/upload.jsp?allowedTypes=jpg,gif</code>.<br/>
 * 其中allowedTypes=jpg,gif参数代表允许上传jpg和gif两种格式的文件,如未指定则不做限制 .<br/>
 * </li>
 * <li>限制上传文件的大小,由在调用上传工具页面时向url附加参数实现.<br/>
 * 如将CustomDropdown的url写成:<br/>
 * <code>/upload/d5/upload.jsp?maxSize=1024</code>.<br/>
 * 其中maxSize=1024参数代表允许上传的文件的大小为1024(单位byte),如未指定则默认为1024000.<br/>
 * </li>
 * </ol>
 * </p>
 */
public class UploadServiceImpl implements UploadService {

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * itsm.isperp.framework.service.UploadService#save(java.io.InputStream,
	 * java.lang.String, java.lang.String, java.lang.String)
	 */
	public UploadInfo save(InputStream inputStream, String fileName,
			String store, String contentType) throws Exception {
		return this.uploadPersister.persist(inputStream, fileName, store,
				contentType);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see itsm.isperp.framework.service.UploadService#save(javax.servlet.http.
	 * HttpServletRequest)
	 */
	public void save(HttpServletRequest request) throws IOException,
			SQLException {
		this.save(request, request.getParameter("uploadPreference"));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see itsm.isperp.framework.service.UploadService#save(javax.servlet.http.
	 * HttpServletRequest, java.lang.String)
	 */
	public void save(HttpServletRequest request, String uploadPreference)
			throws IOException, SQLException {
		if (!StringUtils.hasText(uploadPreference)) {
			uploadPreference = getDefaultDefintion();
		}
		this.save(request, new DefaultUploadPreferenceImpl(uploadPreference));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see itsm.isperp.framework.service.UploadService#save(javax.servlet.http.
	 * HttpServletRequest, itsm.isperp.framework.upload.UploadPreference)
	 */
	public void save(HttpServletRequest request,
			UploadPreference uploadPreference) throws IOException, SQLException {
		Assert.notNull(request);
		Assert.notNull(uploadPreference);
		if (null != this.uploadChecker) {
			this.uploadChecker.check(request, uploadPreference);
		}
		Assert.notNull(this.uploadPersister, "没有合适的UploadPersister");
		this.uploadPersister.persist(request, uploadPreference);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see itsm.isperp.framework.service.UploadService#get(java.lang.String,
	 * boolean)
	 */
	public UploadInfo get(String id, boolean fetchContent) throws IOException,
			SQLException {
		Assert.notNull(this.uploadPersister, "没有合适的UploadPersister");
		UploadInfo uploadInfo = this.uploadPersister.get(id, fetchContent);
		return uploadInfo;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * itsm.isperp.framework.service.UploadService#getUploadInfosByName(java
	 * .lang.String)
	 */
	public Collection<UploadInfo> getUploadInfosByName(String name,
			boolean fetchContent) throws IOException, SQLException {
		return uploadPersister.getUploadInfosByName(name, fetchContent);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see itsm.isperp.framework.service.UploadService#delete(java.lang.String)
	 */
	public void delete(String id) throws IOException, SQLException {
		Assert.notNull(this.uploadPersister, "没有合适的UploadPersister");
		this.uploadPersister.delete(id);
	}

	private String getDefaultDefintion() {
		Assert.hasText(this.uploadPreferenceDefinition,
				"必须指定默认的上传控制属性(通过在isperp.properties中定义[isperp.upload.preference])");
		return this.uploadPreferenceDefinition;
	}

	private String uploadPreferenceDefinition = null;
	private UploadChecker uploadChecker = null;
	private UploadPersister uploadPersister = null;

	public String getUploadPreferenceDefinition() {
		return uploadPreferenceDefinition;
	}

	public void setUploadPreferenceDefinition(String uploadPreferenceDefinition) {
		this.uploadPreferenceDefinition = uploadPreferenceDefinition;
	}

	public UploadChecker getUploadChecker() {
		return uploadChecker;
	}

	public void setUploadChecker(UploadChecker uploadChecker) {
		this.uploadChecker = uploadChecker;
	}

	public UploadPersister getUploadPersister() {
		return uploadPersister;
	}

	public void setUploadPersister(UploadPersister uploadPersister) {
		this.uploadPersister = uploadPersister;
	}
}
